import { getAxiosInstance } from './axiosReq.js';
import axios from 'axios';
import config from '@/config'

const execingReq = {};
//  res,expire
const cacheStore = {};
/** 缓存时间 */
const defCacheExpireTime = 10000;
// setInterval(() => {
//     console.log(execingReq);
// }, 1000);
// 显示 Loading 方法实现
const showLoading = () => { };
const hideLoading = () => { };

/**
 * 发起请求 (PC 版实现)
 * @param {Object} options 
 *  url: options.url,
    data: options.data,
    header: getHttpHeaders(),
    method: options.method || 'get',
    timeout: 30000
 */
function excuteRequest(options) {
    const urltag = options.url+'|'+objToStr(options.data);
    let reqTast = {};
    options.cancelToken = new axios.CancelToken(c => reqTast.abort = c);
    const prom = getAxiosInstance().request(options);

    let _abortFunc;
    const _abortPrm = new Promise((resolve, reject) => {
        _abortFunc = desc => reject(desc || 'break');
    });
    const newProm = Promise.race([prom, _abortPrm]);
    const abort = () => {
        reqTast.abort();
        // console.log('reqTast.abort', reqTast.abort);
        // if (SystemInfo.platform!='ios') {
        //     reqTast.abort();
        // } else {
        //     _abortFunc();
        // }
        console.log('中止重复请求成功');
    }
    execingReq[urltag] = { abort };
    return newProm;
}

/**
 * http 网络请求
 * @param {Object} options 
 * @param {String} options.url 链接
 * @param {Object} options.data 数据
 * @param {String} options.method 方法
 * @param {String} options.root 根路径,若不传则使用默认 apiRoot
 * @param {String} options.hasLoading?  是否使用全局 Loading :默认为 True
 * @param {boolean} options.useCache?  是否使用请求缓存 :默认为 False
 */
export function http(options) {
    // console.log('options.url', options.url);
    // console.log('execingReq', execingReq);
    // console.log('execingReq[options.url]', execingReq[options.url]);
    let urltag;
    return new Promise((resolve, reject) => {
        let root = options.root || config.apiRoot;
        options.url = root + handleUrl(options.url);
        urltag = options.url+'|'+objToStr(options.data);
        if (options.useCache!=true) {
            // 针对该项目,默认为 false
            options.useCache = false;
        }
        // 开启数据缓存则短时间相同请求优先使用缓存
        if (options.useCache==false) {
            const cacheData = cacheStore[urltag];
            if (cacheData&&cacheData.expire>new Date().getTime()) {
                // 数据存在且未过期,直接使用缓存数据
                console.log('使用cache数据');
                resolve(cacheData.res);
                return;
            }
        }
        // 阻止同请求并发执行(后执行覆盖前执行)
        if (execingReq[urltag]) {
            if (options.method.toUpperCase() == 'POST') {
                console.log('中止正在进行中的重复请求', urltag);
                reject('break');
                return;
            }
        }
        if (options.hasLoading != false) showLoading();
        return excuteRequest({
            url: options.url,
            data: options.data,
            method: options.method || 'get',
            timeout: 3000,
            headers:options.headers
        }).then(result => {
            if (options.useCache == true) {
                // 存储缓存数据
                cacheStore[urltag]={
                    res:result,
                    expire:new Date().getTime()+defCacheExpireTime
                };
                // 检查并去除过期数据
                Object.keys(cacheStore).forEach(key=>{
                    const item = cacheStore[key];
                    if (item.expire<=new Date().getTime()) {
                        delete cacheStore[key];
                    }
                })
            }
            resolve(result);
        }).catch(err => reject(err));
    }).then((res) => {
        // 过滤器负责处理
        // if (res.data.data) {
        //     var obj = res.data.data.replace(/\s*/g, "");
        //     var datas = JSON.parse(desDecrypt(obj));
        //     if (res.data.value) {
        //         delete res.data.value
        //     }
        //     res.data.value = datas
        // }
        // let val;
        // if (res.data.code == 200) {
        //     val = res.data;
        // } else {
        //     val = res.data;
        // }
        if (options.hasLoading != false) hideLoading();
        setTimeout(() => {
            delete execingReq[urltag];
        }, 300);
        return res.data;
    }).catch((err) => {
        if (options.hasLoading != false) hideLoading();
        setTimeout(() => {
            delete execingReq[urltag];
        }, 300);
        if (err.errMsg && err.errMsg.indexOf('request:fail abort') > -1) {
            throw 'break';
        } else {
            throw err;
        }
    });
}
export function httpPost(url, data, options) {
    if (!options) options = {};
    options.url = url;
    options.data = data;
    options.method = 'POST';
    return http(options)
}
export function httpGet(url, data, options) {
    if (!options) options = {};
    options.url = url;
    options.data = data;
    options.method = 'GET';
    return http(options)
}
export function httpDel(url, data, options) {
    if (!options) options = {};
    options.url = url;
    options.data = data;
    options.method = 'DELETE';
    return http(options)
}

export function httpPut(url, data, options) {
    if (!options) options = {};
    options.url = url;
    options.data = data;
    options.method = 'PUT';
    return http(options)
}

/**
 * 默认添加/v1 兼容老接口调用
 * @param {String} urlStr 
 */
function handleUrl(urlStr) {
   
    return urlStr;
}


 //object转string,用于签名计算
function objToStr(args) {
    if (!args)return '';
    var keys = Object.keys(args)
    keys = keys.sort() //参数名ASCII码从小到大排序（字典序）；
    var newArgs = {}
    keys.forEach(function (key) {
        if (args[key] != "" && args[key] != 'undefined') {  //如果参数的值为空不参与签名；
            newArgs[key] = args[key]  //参数名区分大小写；
        }
    })
    var string = ''
    for (var k in newArgs) {
        string += '&' + k + '=' + newArgs[k]
    }
    string = string.substr(1)
    return string
}